import subprocess
import re
from typing import List, Dict, Optional, Tuple
from dataclasses import dataclass
from config.settings import settings


@dataclass
class Device:
    """设备信息模型"""
    device_id: str
    status: str
    product: Optional[str] = None
    model: Optional[str] = None
    transport_id: Optional[str] = None


class ADBClient:
    """ADB客户端核心类"""
    
    def __init__(self):
        self.adb_path = settings.get_adb_path()
        self.timeout = settings.get_command_timeout()
    
    def execute_command(self, command: List[str]) -> Tuple[bool, str, str]:
        """
        执行ADB命令
        
        Args:
            command: 命令列表，如 ['devices']
            
        Returns:
            (success, stdout, stderr): 执行结果
        """
        try:
            full_command = [self.adb_path] + command
            result = subprocess.run(
                full_command,
                capture_output=True,
                text=True,
                timeout=self.timeout
            )
            
            success = result.returncode == 0
            return success, result.stdout, result.stderr
            
        except subprocess.TimeoutExpired:
            return False, "", f"命令执行超时: {' '.join(command)}"
        except FileNotFoundError:
            return False, "", f"ADB命令未找到: {self.adb_path}"
        except Exception as e:
            return False, "", f"命令执行异常: {str(e)}"
    
    def list_devices(self) -> List[Device]:
        """
        获取连接的设备列表
        
        Returns:
            设备列表
        """
        success, stdout, stderr = self.execute_command(['devices', '-l'])
        
        if not success:
            raise Exception(f"获取设备列表失败: {stderr}")
        
        return self._parse_device_list(stdout)
    
    def _parse_device_list(self, output: str) -> List[Device]:
        """
        解析设备列表输出
        
        Args:
            output: adb devices -l 的输出
            
        Returns:
            解析后的设备列表
        """
        devices = []
        lines = output.strip().split('\n')
        
        for line in lines:
            # 跳过标题行和空行
            if not line.strip() or 'List of devices' in line:
                continue
            
            # 解析设备行
            # 格式: device_id device status product:product_name model:model_name transport_id:transport_id
            parts = line.strip().split()
            if len(parts) < 2:
                continue
            
            device_id = parts[0]
            status = parts[1]
            
            # 解析额外信息
            product = None
            model = None
            transport_id = None
            
            for part in parts[2:]:
                if part.startswith('product:'):
                    product = part.split(':', 1)[1]
                elif part.startswith('model:'):
                    model = part.split(':', 1)[1]
                elif part.startswith('transport_id:'):
                    transport_id = part.split(':', 1)[1]
            
            device = Device(
                device_id=device_id,
                status=status,
                product=product,
                model=model,
                transport_id=transport_id
            )
            devices.append(device)
        
        return devices
    
    def get_device_info(self, device_id: str) -> Dict[str, str]:
        """
        获取设备详细信息
        
        Args:
            device_id: 设备ID
            
        Returns:
            设备详细信息字典
        """
        info = {}
        
        # 获取设备属性
        success, stdout, stderr = self.execute_command(['-s', device_id, 'shell', 'getprop'])
        if success:
            info['properties'] = stdout
        
        # 获取设备型号
        success, stdout, stderr = self.execute_command(['-s', device_id, 'shell', 'getprop', 'ro.product.model'])
        if success:
            info['model'] = stdout.strip()
        
        # 获取Android版本
        success, stdout, stderr = self.execute_command(['-s', device_id, 'shell', 'getprop', 'ro.build.version.release'])
        if success:
            info['android_version'] = stdout.strip()
        
        # 获取设备制造商
        success, stdout, stderr = self.execute_command(['-s', device_id, 'shell', 'getprop', 'ro.product.manufacturer'])
        if success:
            info['manufacturer'] = stdout.strip()
        
        return info
    
    def check_device_status(self, device_id: str) -> bool:
        """
        检查设备连接状态
        
        Args:
            device_id: 设备ID
            
        Returns:
            设备是否在线
        """
        success, stdout, stderr = self.execute_command(['-s', device_id, 'shell', 'echo', 'test'])
        return success
